package org.ruoyi.common.dhuman.backup;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 视频抠图处理器
 * 使用FFmpeg对视频进行抠图处理，生成透明背景视频
 */
public class VideoMattingProcessor {

	private static final String FFMPEG_PATH = "ffmpeg";
	private static final String DEFAULT_PICTURE_PATH = "C:\\Users\\Admin\\Videos";

	/**
	 * 对视频进行抠图处理
	 *
	 * @param sourceVideoName 源视频文件名（需要被抠图的视频）
	 * @param maskVideoName   遮罩视频文件名（用于抠图的蒙版视频）
	 * @param outputVideoName 输出视频文件名
	 * @param picturePath     视频文件所在目录路径
	 * @throws IOException          IO异常
	 * @throws InterruptedException 中断异常
	 */
	public void processVideoMatting(String sourceVideoName, String maskVideoName,
									String outputVideoName, String picturePath)
		throws IOException, InterruptedException {

		// 构建完整的文件路径
		String sourceVideoPath = picturePath + File.separator + sourceVideoName;
		String maskVideoPath = picturePath + File.separator + maskVideoName;
		String outputVideoPath = picturePath + File.separator + outputVideoName;

		// 检查输入文件是否存在
		if (!new File(sourceVideoPath).exists()) {
			throw new IOException("源视频文件不存在: " + sourceVideoPath);
		}

		if (!new File(maskVideoPath).exists()) {
			throw new IOException("遮罩视频文件不存在: " + maskVideoPath);
		}

		// 构建FFmpeg命令
		List<String> command = buildFFmpegCommand(sourceVideoPath, maskVideoPath, outputVideoPath);

		// 执行FFmpeg命令
		executeCommand(command);
	}

	/**
	 * 对视频进行抠图处理（使用默认路径）
	 *
	 * @param sourceVideoName 源视频文件名
	 * @param maskVideoName   遮罩视频文件名
	 * @param outputVideoName 输出视频文件名
	 * @throws IOException          IO异常
	 * @throws InterruptedException 中断异常
	 */
	public void processVideoMatting(String sourceVideoName, String maskVideoName, String outputVideoName)
		throws IOException, InterruptedException {
		processVideoMatting(sourceVideoName, maskVideoName, outputVideoName, DEFAULT_PICTURE_PATH);
	}

	/**
	 * 构建FFmpeg命令
	 *
	 * @param sourceVideoPath 源视频路径
	 * @param maskVideoPath   遮罩视频路径
	 * @param outputVideoPath 输出视频路径
	 * @return FFmpeg命令列表
	 */
	private List<String> buildFFmpegCommand(String sourceVideoPath, String maskVideoPath, String outputVideoPath) {
		List<String> command = new ArrayList<>();
		command.add(FFMPEG_PATH);
		command.add("-i");
		// 输入源视频
		command.add(sourceVideoPath);
		command.add("-i");
		// 输入遮罩视频
		command.add(maskVideoPath);

		// 使用滤镜处理视频抠图
		command.add("-filter_complex");
		// 修改滤镜命令，添加format过滤器确保像素格式兼容
		command.add("[1:v]format=rgba,alphaextract[alpha];[0:v][alpha]alphamerge");

		// 设置输出格式和编码参数
		command.add("-c:v");
		// 使用H.264编码
		command.add("libx264");
		command.add("-crf");
		// 视频质量控制
		command.add("23");
		command.add("-preset");
		// 编码速度和压缩率的平衡
		command.add("medium");
		command.add("-pix_fmt");
		// 像素格式（支持alpha通道）
		command.add("yuva420p");
		command.add("-c:a");
		// 音频流重新编码以兼容输出格式
		command.add("aac");
		command.add("-b:a");
		// 音频比特率
		command.add("128k");
		// 输出文件
		command.add(outputVideoPath);

		return command;
	}

	/**
	 * 执行命令
	 *
	 * @param command 命令列表
	 * @throws IOException          IO异常
	 * @throws InterruptedException 中断异常
	 */
	private void executeCommand(List<String> command) throws IOException, InterruptedException {
		System.out.println("执行命令: " + String.join(" ", command));

		ProcessBuilder processBuilder = new ProcessBuilder(command);
		processBuilder.redirectErrorStream(true);
		Process process = processBuilder.start();

		// 读取命令执行输出
		try (BufferedReader reader = new BufferedReader(
			new InputStreamReader(process.getInputStream()))) {
			String line;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		}

		int exitCode = process.waitFor();
		if (exitCode != 0) {
			throw new IOException("FFmpeg处理失败，退出码: " + exitCode);
		}
	}

	/**
	 * 示例用法
	 */
	public static void main(String[] args) {
		VideoMattingProcessor processor = new VideoMattingProcessor();
		try {
			// 对result.mp4和mask.mp4进行抠图处理，生成output.mp4
			String outputFile = "output_" + System.currentTimeMillis() + ".mp4";
			processor.processVideoMatting("result.mp4", "mask.mp4", outputFile);
			System.out.println("视频抠图处理完成！输出文件位于: C:\\Users\\Admin\\Videos\\" + outputFile);
		} catch (IOException | InterruptedException e) {
			System.err.println("视频处理失败: " + e.getMessage());
			e.printStackTrace();
		}
	}
}
